/**
 * LoginWindow.java 2008-05-14
 * 
 * Linker is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

package linker.gui;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.util.Properties;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import linker.LocalVariablesManager;
import linker.account.LoginProgress;
import linker.account.ManageAccount;
import linker.account.PasswordMask;

/**
 * The window for login.It read saved accounts from '/info/user.info' and set
 * them in the combo box.also save password in that file.And judge logining is
 * success or not,and change window by the returned information.
 * 
 * @version 2008-05-19
 * @author Jianfeng tujf.cn@gmail.com
 * 
 */

public class LoginWindow extends JFrame implements ItemListener, ActionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * The login button.
	 */
	private JButton loginButton;

	/**
	 * The default length of JPasswordField.
	 */
	private final int passwordFieldLength = 15;

	/**
	 * The Field for password.
	 */
	private JPasswordField passwordField = new JPasswordField(
			passwordFieldLength);

	/**
	 * The combobox to show the saved account.
	 */
	private JComboBox box;

	/**
	 * The checkBox to show whether saved the current account's password or not.
	 */
	private JCheckBox savePassword = new JCheckBox(LocalVariablesManager
			.getLocalVariables("LoginWindow.SavePasswordCheckBox"));

	/**
	 * The saved accounts.
	 */
	private Properties accounts = new Properties();

	/**
	 * The logining account's username.
	 */
	private String username;

	/**
	 * The logining account's password.
	 */
	private String password;

	/**
	 * 
	 */
	public LoginWindow() {
		super(LocalVariablesManager.getLocalVariables("LoginWindow"));
		setName("LoginWindow");
		setIconImage(ManageAccount.getLogo());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		Toolkit.getDefaultToolkit().addAWTEventListener(
				WindowSaver.getWindowSaver(), AWTEvent.WINDOW_EVENT_MASK);

		Container container = getContentPane();
		JPanel p = new JPanel();
		GroupLayout layout = new GroupLayout(p);
		p.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		JLabel nameLabel = new JLabel(LocalVariablesManager
				.getLocalVariables("LoginWindow.UsernameLabel"));
		accounts = ManageAccount.getAccounts();
		box = new JComboBox();
		Object[] names = accounts.keySet().toArray();
		boolean first = true;
		String tempPassword;
		for (int i = 0; i < names.length; i++) {
			String name = (String) names[i];
			if (name.endsWith("host") || name.endsWith("port")
					|| name.endsWith("domain")) {
				continue;
			}

			if (first) {
				first = false;
				tempPassword = accounts.getProperty((String) names[i]);
				if (tempPassword != null && tempPassword.length() > 0) {
					passwordField.setText(PasswordMask
							.getPassword(tempPassword));
					savePassword.setSelected(true);
				}
			}
			box.addItem(names[i]);
		}
		box.addItemListener(this);
		box.setEditable(true);

		JLabel passwordLabel = new JLabel(LocalVariablesManager
				.getLocalVariables("LoginWindow.PasswordLabel"));

		passwordField.addActionListener(this);
		loginButton = new JButton(LocalVariablesManager
				.getLocalVariables("LoginWindow.LoginButton"));
		loginButton.setMnemonic(KeyEvent.VK_L);
		loginButton.addActionListener(this);
		savePassword.addItemListener(this);
		savePassword.addActionListener(this);

		layout.setHorizontalGroup(layout.createSequentialGroup().addGroup(
				layout.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(nameLabel).addComponent(passwordLabel))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.LEADING)
								.addComponent(box).addComponent(passwordField)
								.addGroup(
										layout.createSequentialGroup()
												.addComponent(loginButton))
								.addComponent(savePassword))

		);
		layout.setVerticalGroup(layout.createSequentialGroup().addGroup(
				layout.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(nameLabel).addComponent(box)).addGroup(
				layout.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(passwordLabel)
						.addComponent(passwordField)).addGroup(
				layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
						.addComponent(loginButton)).addGroup(
				layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
						.addComponent(savePassword)));
		container.add(p, BorderLayout.NORTH);

		// Set window size and location.
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}

	/**
	 * Listen when the account in the combobox changed.
	 * 
	 * @param e
	 *            ItemEvent.
	 */
	public final void itemStateChanged(final ItemEvent e) {
		if (e.getSource() == box) {
			if (box.getSelectedIndex() != -1) {
				String tempPassword = accounts.getProperty((String) box
						.getSelectedItem());
				passwordField.setText(PasswordMask.getPassword(tempPassword));

				if (tempPassword == null || tempPassword.length() == 0) {
					savePassword.setSelected(false);
				} else {
					savePassword.setSelected(true);
				}

			} else {
				passwordField.setText("");
				savePassword.setSelected(false);
			}
		}
	}

	/**
	 * The login function.
	 */
	public final void login() {
		// judge whether the username or password are empty
		if ((box.getSelectedIndex() == -1 && ((JTextField) box.getEditor()
				.getEditorComponent()).getText() == "")
				|| passwordField.getPassword().length == 0) {
			JOptionPane.showMessageDialog(null,
					"You shoud input username and password");
			return;
		}

		if (box.getSelectedIndex() == -1) {
			username = ((JTextField) box.getEditor().getEditorComponent())
					.getText();
		} else {
			username = box.getSelectedItem().toString();
		}
		password = new String(passwordField.getPassword());

		Thread t = new Thread(new LoginProgress(this, username, password, null,
				null, null));
		t.start();
		setVisible(false);
	}

	/**
	 * Called when loginSuccess. It save the current account and dispose
	 * loginWindow.
	 */
	public final void loginSuccess() {
		if (savePassword.isSelected()) {
			ManageAccount.addAccount(username, PasswordMask
					.setPassword(password), null, null, null);
		} else {
			ManageAccount.addAccount(username, "", null, null, null);
		}

		this.dispose();
	}

	/**
	 * Listen the button action.
	 * 
	 * @param e
	 *            ActionEvent.
	 */
	public final void actionPerformed(final ActionEvent e) {
		if (e.getSource() == loginButton || e.getSource() == passwordField) {

			// login
			login();
		} else if (e.getSource() == savePassword) {

			// judeg whether savePassword is selected
			if (savePassword.isSelected()) {
				int i = JOptionPane.showConfirmDialog(this,
						"It is not safe to save password local,Confirm it?",
						"Confirm selection", JOptionPane.OK_CANCEL_OPTION);
				if (i == JOptionPane.CANCEL_OPTION) {
					savePassword.setSelected(false);
				}
			}
		}
	}
}
